﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SqlBlocks.Drivers;

namespace SqlBlocks
{
    public class MigrationFilter
    {
        public List<string> Include { get; private set; }
        public List<string> Exclude { get; private set; }

        public double Version { get; set; }

        public MigrationRunMode Mode { get; set; }

        public MigrationFilter()
        {
            this.Include = new List<string>();
            this.Exclude = new List<string>();
        }

        public static MigrationFilter Default { get { return new MigrationFilter(); } }


        Dictionary<string, double> currentVersions;

        public delegate double VersionLookupDelegate(string group);
        public IEnumerable<MigrationDescription> Filter(IEnumerable<MigrationDescription> migrations, VersionLookupDelegate vlookup)
        {

            var validMigrations = migrations.Where(
                m => 
                    IsIncluded(m.Group) && 
                    !IsExcluded(m.Group)
                );

            var groups = (from m in validMigrations select m.Group).Distinct();

            return validMigrations;
        }

        bool IsValidForTarget(string group, VersionLookupDelegate vlookup)
        {
            // If target > currentVersion and currentVersion < mversion <= target
            // If target < currentVersion and currentVersion > mversion >= target
            return true;
        }

        void LoadDbVersions(IEnumerable<string> groups, VersionLookupDelegate vlookup)
        {
            currentVersions = new Dictionary<string, double>(StringComparer.CurrentCultureIgnoreCase);
            foreach (var g in groups)
            {
                currentVersions.Add(g, vlookup(g));
            }
        }

        bool IsIncluded(string group)
        {
            return Include.Count == 0 || IsInList(group, Include);
        }

        bool IsExcluded(string group)
        {
            return IsInList(group, Exclude);
        }

        bool IsInList(string group, IEnumerable<string> groups)
        {
            foreach (var g in groups)
            {
                if (string.Equals(group, g, StringComparison.CurrentCultureIgnoreCase))
                {
                    return true;
                }
            }
            return false;
        }
    }
}
